﻿#region - 版 本 注 释 -
/*----------------------------------------------------------------
 * 版权所有 (c) 2024   保留所有权利。
 * CLR版本：4.0.30319.42000
 * 机器名称：DESKTOP-GLJ2Q8J
 * 公司名称：
 * 命名空间：AutoCAD.EntityTool
 * 唯一标识：3b617350-31ef-4d14-b07c-78290c7493b3
 * 文件名：EntityTools
 * 当前用户域：DESKTOP-GLJ2Q8J
 * 
 * 创建者：Guo-79991
 * 电子邮箱：799919859@qq.com
 * 创建时间：2024/7/15 11:53:52
 * 版本：V1.0.0
 *
 * 功能描述(Description):
 * 参考文档(Reference):
 * 数据表(Tables):
 * 作者(Author):Guo
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/
#endregion - 版 本 注 释 -





using Color = Autodesk.AutoCAD.Colors.Color;

namespace AutoCAD.EntityTools
{
    /// <summary>
    /// 实体扩展工具
    /// </summary>
    public static class EntityTools
    {
        /// <summary>
        /// 通过ObjectId数组获取对应的实体数组。
        /// </summary>
        /// <param name="db">AutoCAD数据库实例。</param>
        /// <param name="objIds">要查询的ObjectId数组。</param>
        /// <returns>与ObjectId数组对应的实体数组。如果传入的ObjectId数组为空或长度为零，则返回null。</returns>
        /// <remarks>
        /// 此方法使用事务来安全地访问数据库中的实体。每个ObjectId都会被查询，并转换为对应的实体。
        /// 如果传入的ObjectId不存在或无法转换为实体，则对应位置在返回的数组中将为null。
        /// </remarks>
        public static Entity[] ToObjectIdGetEntity(this Database db, params ObjectId[] objIds)
        {
            if (objIds.Length <= 0)
                return null;
            Entity[] ents = new Entity[objIds.Length];
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                for (int i = 0; i < objIds.Length; i++)
                {
                    DBObject dBObj = objIds[i].GetObject(OpenMode.ForRead);
                    ents[i] = (Entity)dBObj;
                }
            }
            return ents;
        }

        /// <summary>
        /// 通过ObjectId得到实体
        /// </summary>
        /// <param name="objId">要查询的ObjectId</param>
        /// <param name="db">图像数据库</param>
        /// <returns>实体</returns>
        public static Entity ToObjectIdGetEntity(this Database db, ObjectId objId)
        {

            Entity ent = null;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {

                DBObject dBObj = objId.GetObject(OpenMode.ForRead);
                ent = (Entity)dBObj;

            }
            return ent;
        }

        ///// <summary>
        ///// 移动实体
        ///// </summary>
        ///// <param name="id">实体的ObjectId</param>
        ///// <param name="sourcePt">移动源点</param>
        ///// <param name="targetPt">移动的目标点</param>
        //public static void Move(this ObjectId id, Point3d sourcePt, Point3d targetPt)
        //{
        //    //构建用于移动实体的矩阵
        //    var vector = sourcePt.GetVectorTo(targetPt);
        //    var mt = Matrix3d.Displacement(vector);
        //    //以写的方式打开id表示的实体对象
        //    var ent = id.GetObject(OpenMode.ForWrite) as Entity;
        //    //对实体实施移动
        //    ent.TransformBy(mt);
        //    //为防止错误,切换实体为读的状态
        //    ent.DowngradeOpen();
        //}
        /// <summary>
        /// 移动实体（优化版）
        /// </summary>
        /// <param name="id">实体的ObjectId</param>
        /// <param name="sourcePt">移动源点</param>
        /// <param name="targetPt">移动的目标点</param>
        /// <returns>是否移动成功</returns>
        public static bool Move(this ObjectId id, Point3d sourcePt, Point3d targetPt)
        {
            // 验证参数有效性
            if (id == null || id.IsNull || !id.IsValid)
            {
                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n错误：无效的实体ID");
                return false;
            }

            if (sourcePt == null || targetPt == null)
            {
                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n错误：点参数不能为null");
                return false;
            }

            // 检查点是否有效（非无穷大和非NaN）
            if (!IsValidPoint(sourcePt) || !IsValidPoint(targetPt))
            {
                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n错误：无效的坐标点");
                return false;
            }

            Transaction tr = null;
            try
            {
                // 获取当前文档数据库
                var db = id.Database;
                tr = db.TransactionManager.StartTransaction();

                // 以写的方式打开实体对象（添加类型检查）
                var ent = tr.GetObject(id, OpenMode.ForWrite) as Entity;

                if (ent == null)
                {
                    Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n错误：指定的ID不是有效实体");
                    return false;
                }

                // 构建移动向量和变换矩阵
                var vector = sourcePt.GetVectorTo(targetPt);
                var mt = Matrix3d.Displacement(vector);

                // 应用变换
                ent.TransformBy(mt);

                // 提交事务
                tr.Commit();
                return true;
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\nCAD错误：{ex.Message}");
                tr?.Abort();
                return false;
            }
            catch (System.Exception ex)
            {
                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\n系统错误：{ex.Message}");
                tr?.Abort();
                return false;
            }
            finally
            {
                tr?.Dispose();
            }
        }





        /// <summary>
        /// 创建直线并添加到模型空间
        /// </summary>
        public static ObjectId AddLineToModelSpace(this Database db, Point3d startPoint, Point3d endPoint, short colorIndex = 1)
        {
            Line line = new Line(startPoint, endPoint)
            {
                ColorIndex = colorIndex
            };

            return db.AddEntityToModelSpace(line);
        }




        /// <summary>
        /// 检查点坐标是否有效
        /// </summary>
        private static bool IsValidPoint(Point3d point)
        {
            return !double.IsInfinity(point.X) && !double.IsNaN(point.X) &&
                   !double.IsInfinity(point.Y) && !double.IsNaN(point.Y) &&
                   !double.IsInfinity(point.Z) && !double.IsNaN(point.Z);
        }

        /// <summary>
        /// 移动实体
        /// </summary>
        /// <param name="ent">实体</param>
        /// <param name="sourcePt">移动源点</param>
        /// <param name="targetPt">移动的目标点</param>
        public static void Move<TEntity>(this TEntity ent, Point3d sourcePt, Point3d targetPt)
            where TEntity : Entity
        {
            if (ent.IsNewObject)  //如果是还未被添加到数据库中的新实体
            {
                //构造用于移动实体的矩阵
                var vector = targetPt.GetVectorTo(sourcePt);
                var mt = Matrix3d.Displacement(vector);
                ent.TransformBy(mt);  //对实体实施移动
            }
            else  //如果是已经够添加到书记库中的实体
            {
                ent.ObjectId.Move(sourcePt, targetPt);
            }
        }
        /// <summary>
        /// 复制实体（安全版本）
        /// </summary>
        /// <param name="id">实体的ObjectId</param>
        /// <param name="sourcePt">复制的源点</param>
        /// <param name="targetPt">复制的目标点</param>
        /// <returns>复制实体的ObjectId，失败返回ObjectId.Null</returns>
        public static ObjectId Copy(this ObjectId id, Point3d sourcePt, Point3d targetPt)
        {
            // 参数有效性检查
            if (id == null || id.IsNull || !id.IsValid)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：无效的实体ID");
                return ObjectId.Null;
            }

            if (sourcePt == null || targetPt == null)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：源点或目标点不能为null");
                return ObjectId.Null;
            }

            // 检查点坐标是否有效
            if (!IsValidPoint(sourcePt) || !IsValidPoint(targetPt))
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：无效的点坐标");
                return ObjectId.Null;
            }

            Database db = id.Database;
            Transaction tr = db.TransactionManager.StartTransaction();

            try
            {
                // 安全获取实体对象
                DBObject dbObj = tr.GetObject(id, OpenMode.ForRead);
                if (dbObj == null)
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：无法获取实体对象");
                    return ObjectId.Null;
                }

                Entity ent = dbObj as Entity;
                if (ent == null)
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：选择的对象不是可复制的实体");
                    return ObjectId.Null;
                }

                // 构建位移向量和变换矩阵
                // 注意：这里应该是sourcePt到targetPt的向量，而不是反过来
                var vector = sourcePt.GetVectorTo(targetPt);
                var mt = Matrix3d.Displacement(vector);

                // 获取实体的复制件
                Entity entCopy = ent.GetTransformedCopy(mt) as Entity;
                if (entCopy == null)
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：无法创建实体副本");
                    return ObjectId.Null;
                }

                // 将复制的实体对象添加到模型空间
                ObjectId copyId = db.AddEntityToModelSpace(entCopy);

                tr.Commit();
                return copyId;
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                tr?.Abort();
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage($"\nCAD操作错误：{ex.Message}");
                return ObjectId.Null;
            }
            catch (System.Exception ex)
            {
                tr?.Abort();
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage($"\n系统错误：{ex.Message}");
                return ObjectId.Null;
            }
            finally
            {
                tr?.Dispose();
            }
        }


        /// <summary>
        /// 旋转实体（安全版本）
        /// </summary>
        /// <param name="id">实体ObjectId</param>
        /// <param name="basePt">旋转基点</param>
        /// <param name="angle">旋转角度（弧度）</param>
        /// <returns>是否旋转成功</returns>
        public static bool Rotate(this ObjectId id, Point3d basePt, double angle)
        {
            // 参数有效性检查
            if (id == null || id.IsNull || !id.IsValid)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：无效的实体ID");
                return false;
            }

            if (basePt == null)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：旋转基点不能为null");
                return false;
            }

            // 检查角度是否有效（避免过小的角度）
            if (Math.Abs(angle) < 1e-10)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n警告：旋转角度太小，忽略操作");
                return true; // 角度太小，视为成功但不执行操作
            }

            // 检查基点坐标是否有效
            if (!IsValidPoint(basePt))
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：无效的基点坐标");
                return false;
            }

            Transaction tr = null;
            try
            {
                Database db = id.Database;
                tr = db.TransactionManager.StartTransaction();

                // 安全获取实体对象
                DBObject dbObj = tr.GetObject(id, OpenMode.ForWrite);
                if (dbObj == null)
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：无法获取实体对象");
                    return false;
                }

                Entity ent = dbObj as Entity;
                if (ent == null)
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：选择的对象不是可旋转的实体");
                    return false;
                }

                // 创建旋转矩阵（绕Z轴旋转）
                Matrix3d mt = Matrix3d.Rotation(angle, Vector3d.ZAxis, basePt);

                // 应用变换
                ent.TransformBy(mt);

                tr.Commit();
                return true;
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                tr?.Abort();
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage($"\nCAD操作错误：{ex.Message}");
                return false;
            }
            catch (System.Exception ex)
            {
                tr?.Abort();
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage($"\n系统错误：{ex.Message}");
                return false;
            }
            finally
            {
                tr?.Dispose();
            }
        }

        /// <summary>
        /// 旋转实体（角度制版本）
        /// </summary>
        /// <param name="id">实体ObjectId</param>
        /// <param name="basePt">旋转基点</param>
        /// <param name="angleInDegrees">旋转角度（度）</param>
        /// <returns>是否旋转成功</returns>
        public static bool RotateDegrees(this ObjectId id, Point3d basePt, double angleInDegrees)
        {
            // 将角度转换为弧度
            double angleInRadians = angleInDegrees * (Math.PI / 180.0);
            return id.Rotate(basePt, angleInRadians);
        }


        ///// <summary>
        ///// 缩放
        ///// </summary>
        ///// <param name="id">实体的ObjectId</param>
        ///// <param name="basePt">缩放基点</param>
        ///// <param name="scaleFactor">缩放比例</param>
        //public static void Scale(this ObjectId id, Point3d basePt, double scaleFactor)
        //{
        //    var mt = Matrix3d.Scaling(scaleFactor, basePt);
        //    var ent = id.GetObject(OpenMode.ForWrite) as Entity;
        //    ent.TransformBy(mt);
        //}



        /// <summary>
        /// 显示所有实体
        /// </summary>
        public static void ShowAllEntities(this Document doc)
        {
            // 获取当前文档和数据库
            //Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            // 开始事务
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                // 打开模型空间块表记录
                BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                // 遍历模型空间中的所有实体
                foreach (ObjectId entityId in modelSpace)
                {
                    Entity ent = trans.GetObject(entityId, OpenMode.ForWrite) as Entity;
                    if (ent != null)
                    {
                        // 显示实体
                        ent.Visible = true;
                    }
                }

                // 提交事务以应用更改
                trans.Commit();
            }

            // 刷新屏幕以显示更改
            ed.Regen();
        }
        /// <summary>
        /// 隐藏除指定实体列表外的所有其他实体
        /// </summary>
        /// <param name="objectIdsToKeepVisible">要保持可见的实体ObjectId列表</param>
        public static void HideOtherEntities(this List<ObjectId> objectIdsToKeepVisible)
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                // 获取模型空间
                BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                BlockTableRecord modelSpace = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

                // 遍历模型空间中的所有实体
                foreach (ObjectId entityId in modelSpace)
                {
                    // 检查当前实体是否在要保持可见的列表中
                    if (!objectIdsToKeepVisible.Contains(entityId))
                    {
                        Entity ent = trans.GetObject(entityId, OpenMode.ForWrite) as Entity;
                        if (ent != null)
                        {
                            // 隐藏实体
                            ent.Visible = false;
                        }
                    }
                }

                // 提交事务以应用更改
                trans.Commit();
            }

            // 刷新屏幕以显示更改
            ed.Regen();
        }





        #region 高亮


        //    /// <summary>
        //    /// 高亮显示指定的实体列表
        //    /// </summary>
        //    /// <param name="objectIds">要高亮的实体ObjectId列表</param>
        //    public static void HighlightEntities(this List<ObjectId> objectIds)
        //    {
        //        Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
        //        Database db = doc.Database;
        //        Editor ed = doc.Editor;

        //        using (Transaction trans = db.TransactionManager.StartTransaction())
        //        {
        //            foreach (ObjectId oid in objectIds)
        //            {
        //                Entity ent = trans.GetObject(oid, OpenMode.ForRead) as Entity;
        //                if (ent != null)
        //                {
        //                    // 高亮显示实体
        //                    ent.Highlight();
        //                }
        //            }

        //            // 提交事务以保留高亮状态
        //            trans.Commit();
        //        }

        //        // 刷新屏幕以显示高亮效果
        //        ed.Regen();
        //    }
        //    public static bool HighlightEntity<TEntity>(this TEntity entity, Transaction tr)
        //where TEntity : Entity
        //    {
        //        var ent = tr.GetObject(entity.ObjectId, OpenMode.ForRead) as Entity;
        //        if (ent == null) return false;
        //        ent.Highlight();

        //        return true;
        //    }












        private static readonly HashSet<ObjectId> _highlightedEntities = new HashSet<ObjectId>();

        /// <summary>
        /// 高亮显示指定的实体列表
        /// </summary>
        /// <param name="objectIds">要高亮的实体ObjectId列表</param>
        /// <param name="regenerate">是否刷新视图</param>
        /// <returns>成功高亮的实体数量</returns>
        public static int HighlightEntities(this IEnumerable<ObjectId> objectIds, bool regenerate = true)
        {
            if (objectIds == null)
                return 0;

            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            int highlightedCount = 0;

            try
            {
                using (Transaction trans = db.TransactionManager.StartTransaction())
                {
                    foreach (ObjectId oid in objectIds)
                    {
                        if (!oid.IsValid || oid.IsNull || oid.IsErased)
                            continue;

                        Entity ent = trans.GetObject(oid, OpenMode.ForRead) as Entity;
                        if (ent != null && ent.HighlightEntity(trans))
                        {
                            _highlightedEntities.Add(oid);
                            highlightedCount++;
                        }
                    }

                    trans.Commit();
                }

                if (regenerate && highlightedCount > 0)
                {
                    ed.Regen();
                }

                return highlightedCount;
            }
            catch (Exception ex)
            {
                ed.WriteMessage($"\n高亮显示错误: {ex.Message}");
                return 0;
            }
        }

        /// <summary>
        /// 高亮单个实体
        /// </summary>
        /// <typeparam name="TEntity">实体类型</typeparam>
        /// <param name="entity">要高亮的实体</param>
        /// <param name="transaction">事务对象</param>
        /// <returns>是否成功高亮</returns>
        public static bool HighlightEntity<TEntity>(this TEntity entity, Transaction transaction = null)
            where TEntity : Entity
        {
            if (entity == null || !entity.ObjectId.IsValid)
                return false;

            bool useExternalTransaction = transaction != null;
            Transaction trans = transaction;

            try
            {
                if (!useExternalTransaction)
                {
                    trans = entity.ObjectId.Database.TransactionManager.StartTransaction();
                }

                Entity ent = trans.GetObject(entity.ObjectId, OpenMode.ForRead) as Entity;
                if (ent != null)
                {
                    ent.Highlight();
                    _highlightedEntities.Add(entity.ObjectId);
                    return true;
                }

                return false;
            }
            finally
            {
                if (!useExternalTransaction)
                {
                    trans?.Commit();
                    trans?.Dispose();
                }
            }
        }

        /// <summary>
        /// 取消高亮指定的实体列表
        /// </summary>
        /// <param name="objectIds">要取消高亮的实体ObjectId列表</param>
        /// <param name="regenerate">是否刷新视图</param>
        /// <returns>成功取消高亮的实体数量</returns>
        public static int UnhighlightEntities(this IEnumerable<ObjectId> objectIds, bool regenerate = true)
        {
            if (objectIds == null)
                return 0;

            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            int unhighlightedCount = 0;

            try
            {
                using (Transaction trans = db.TransactionManager.StartTransaction())
                {
                    foreach (ObjectId oid in objectIds)
                    {
                        if (!oid.IsValid || oid.IsNull || oid.IsErased)
                            continue;

                        //if (UnhighlightEntity(oid, trans))
                        //{
                        //    _highlightedEntities.Remove(oid);
                        //    unhighlightedCount++;
                        //}

                        Entity ent = trans.GetObject(oid, OpenMode.ForRead) as Entity;
                        if (ent != null && ent.UnhighlightEntity(trans))
                        {
                            _highlightedEntities.Remove(oid);
                            unhighlightedCount++;
                        }
                    }

                    trans.Commit();
                }

                if (regenerate && unhighlightedCount > 0)
                {
                    ed.Regen();
                }

                return unhighlightedCount;
            }
            catch (Exception ex)
            {
                ed.WriteMessage($"\n取消高亮错误: {ex.Message}");
                return 0;
            }
        }

        /// <summary>
        /// 取消高亮单个实体
        /// </summary>
        /// <typeparam name="TEntity">实体类型</typeparam>
        /// <param name="entity">要取消高亮的实体</param>
        /// <param name="transaction">事务对象</param>
        /// <returns>是否成功取消高亮</returns>
        public static bool UnhighlightEntity<TEntity>(this TEntity entity, Transaction transaction = null)
            where TEntity : Entity
        {
            if (entity == null || !entity.ObjectId.IsValid)
                return false;

            bool useExternalTransaction = transaction != null;
            Transaction trans = transaction;

            try
            {
                if (!useExternalTransaction)
                {
                    trans = entity.ObjectId.Database.TransactionManager.StartTransaction();
                }

                Entity ent = trans.GetObject(entity.ObjectId, OpenMode.ForRead) as Entity;
                if (ent != null)
                {
                    ent.Unhighlight();
                    _highlightedEntities.Remove(entity.ObjectId);
                    return true;
                }

                return false;
            }
            finally
            {
                if (!useExternalTransaction)
                {
                    trans?.Commit();
                    trans?.Dispose();
                }
            }
        }

        /// <summary>
        /// 取消所有已高亮的实体
        /// </summary>
        /// <param name="regenerate">是否刷新视图</param>
        /// <returns>成功取消高亮的实体数量</returns>
        public static int UnhighlightAll(bool regenerate = true)
        {
            if (_highlightedEntities.Count == 0)
                return 0;

            int count = UnhighlightEntities(_highlightedEntities.ToList(), regenerate);
            _highlightedEntities.Clear();
            return count;
        }

        /// <summary>
        /// 获取当前所有高亮的实体ObjectId
        /// </summary>
        public static IEnumerable<ObjectId> GetHighlightedEntities()
        {
            return _highlightedEntities.ToList();
        }

        /// <summary>
        /// 检查实体是否处于高亮状态
        /// </summary>
        public static bool IsHighlighted(this ObjectId objectId)
        {
            return _highlightedEntities.Contains(objectId);
        }



        /*调用
         * 
         * 
                 * // 1. 高亮实体列表
        List<ObjectId> selectedIds = ...;
        int highlightedCount = selectedIds.HighlightEntities();

        // 2. 高亮单个实体
        Line line = ...;
        bool success = line.HighlightEntity();

        // 3. 取消高亮实体列表
        selectedIds.UnhighlightEntities();

        // 4. 取消高亮单个实体
        line.UnhighlightEntity();

        // 5. 取消所有高亮
        int unhighlightedCount = EntityHighlightHelper.UnhighlightAll();

        // 6. 检查高亮状态
        bool isHighlighted = someObjectId.IsHighlighted();

        // 7. 获取所有高亮实体
        var highlightedEntities = EntityHighlightHelper.GetHighlightedEntities();
         * 
         */

        #endregion



        /// <summary>
        /// 缩放实体（安全版本）
        /// </summary>
        /// <param name="id">实体的ObjectId</param>
        /// <param name="basePt">缩放基点</param>
        /// <param name="scaleFactor">缩放比例</param>
        /// <returns>是否缩放成功</returns>
        public static bool Scale(this ObjectId id, Point3d basePt, double scaleFactor)
        {
            // 参数验证
            if (id == null || id.IsNull || !id.IsValid)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：无效的实体ID");
                return false;
            }

            if (basePt == null)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：基点不能为null");
                return false;
            }

            if (Math.Abs(scaleFactor) < 1e-10) // 避免过小的缩放因子
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：缩放比例太小");
                return false;
            }

            Transaction tr = null;
            try
            {
                Database db = id.Database;
                tr = db.TransactionManager.StartTransaction();

                // 安全获取实体对象
                DBObject dbObj = tr.GetObject(id, OpenMode.ForWrite);
                if (dbObj == null)
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：无法获取实体对象");
                    return false;
                }

                Entity ent = dbObj as Entity;
                if (ent == null)
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：选择的对象不是可缩放的实体");
                    return false;
                }

                // 创建缩放矩阵
                Matrix3d mt = Matrix3d.Scaling(scaleFactor, basePt);

                // 应用变换
                ent.TransformBy(mt);

                tr.Commit();
                return true;
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                tr?.Abort();
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage($"\nCAD错误：{ex.Message}");
                return false;
            }
            catch (System.Exception ex)
            {
                tr?.Abort();
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage($"\n系统错误：{ex.Message}");
                return false;
            }
            finally
            {
                tr?.Dispose();
            }
        }





        ///// <summary>
        ///// 镜像
        ///// </summary>
        ///// <param name="id">实体ObjectId</param>
        ///// <param name="mirrorPt1">镜像点1</param>
        ///// <param name="mirrorPt2">镜像点2</param>
        ///// <param name="eraseSourceObject">是否删除源对象</param>
        ///// <returns>镜像实体的ObjectId</returns>
        //public static ObjectId Mirror(this ObjectId id, Point3d mirrorPt1, Point3d mirrorPt2, bool eraseSourceObject)
        //{
        //    var miLine = new Line3d(mirrorPt1, mirrorPt2);  // 镜像线
        //    var mt = Matrix3d.Mirroring(miLine);  //镜像矩阵
        //    ObjectId mirrorId = id;
        //    var ent = id.GetObject(OpenMode.ForWrite) as Entity;
        //    //如果删除源对象，则直接对源对象实行镜像变换
        //    if (eraseSourceObject == true)
        //    {
        //        ent.TransformBy(mt);
        //    }
        //    else  //如果不删除源对象，则镜像复制源对象
        //    {
        //        var entCopy = ent.GetTransformedCopy(mt);
        //        mirrorId = id.Database.AddEntityToModelSpace(entCopy);
        //    }
        //    return mirrorId;
        //}
        /// <summary>
        /// 镜像实体（安全版本）
        /// </summary>
        /// <param name="id">实体ObjectId</param>
        /// <param name="mirrorPt1">镜像点1</param>
        /// <param name="mirrorPt2">镜像点2</param>
        /// <param name="eraseSourceObject">是否删除源对象</param>
        /// <returns>镜像实体的ObjectId，失败返回ObjectId.Null</returns>
        public static ObjectId Mirror(this ObjectId id, Point3d mirrorPt1, Point3d mirrorPt2, bool eraseSourceObject)
        {
            // 参数有效性检查
            if (id == null || id.IsNull || !id.IsValid)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：无效的实体ID");
                return ObjectId.Null;
            }

            if (mirrorPt1 == null || mirrorPt2 == null)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：镜像点不能为null");
                return ObjectId.Null;
            }

            // 检查点坐标是否有效
            if (!IsValidPoint(mirrorPt1) || !IsValidPoint(mirrorPt2))
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：无效的镜像点坐标");
                return ObjectId.Null;
            }

            Database db = id.Database;
            Transaction tr = db.TransactionManager.StartTransaction();

            try
            {
                // 安全获取实体对象
                DBObject dbObj = tr.GetObject(id, OpenMode.ForWrite);
                if (dbObj == null)
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：无法获取实体对象");
                    return ObjectId.Null;
                }

                Entity ent = dbObj as Entity;
                if (ent == null)
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：选择的对象不是可镜像的实体");
                    return ObjectId.Null;
                }

                // 创建镜像线和变换矩阵
                var miLine = new Line3d(mirrorPt1, mirrorPt2);
                var mt = Matrix3d.Mirroring(miLine);
                ObjectId mirrorId = ObjectId.Null;

                if (eraseSourceObject)
                {
                    // 直接变换源实体
                    ent.TransformBy(mt);
                    mirrorId = id;
                }
                else
                {
                    // 创建镜像副本
                    Entity entCopy = ent.GetTransformedCopy(mt) as Entity;
                    if (entCopy == null)
                    {
                        Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：无法创建镜像副本");
                        return ObjectId.Null;
                    }

                    mirrorId = db.AddEntityToModelSpace(entCopy);
                }

                tr.Commit();
                return mirrorId;
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                tr.Abort();
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage($"\nCAD操作错误：{ex.Message}");
                return ObjectId.Null;
            }
            catch (System.Exception ex)
            {
                tr.Abort();
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage($"\n系统错误：{ex.Message}");
                return ObjectId.Null;
            }
            finally
            {
                tr.Dispose();
            }
        }





        /// <summary>
        /// 将指定的实体添加到AutoCAD图形数据库中的块表记录（BlockTableRecord）。
        /// </summary>
        /// <typeparam name="TEntity">实体类型，必须继承自AutoCAD的Entity类。</typeparam>
        /// <param name="entity">要添加到数据库的实体对象。</param>
        /// <param name="host">当前的事务对象，用于管理对数据库的操作。</param>
        /// <param name="btr">目标块表记录，实体将被添加到这个记录中。</param>
        /// <returns>返回添加到数据库后实体的ObjectId。</returns>
        /// <remarks>
        /// 此方法执行以下操作：
        /// 1. 将实体附加到指定的块表记录。
        /// 2. 将新创建的实体添加到事务中，确保实体被正确地管理。
        /// 如果传入的实体为null，则方法返回ObjectId.Null。
        /// </remarks>
        public static ObjectId AddToDatabase<TEntity>(this TEntity entity, Transaction host, BlockTableRecord btr)
            where TEntity : Entity
        {
            if (entity is null) return ObjectId.Null;
            var id = btr.AppendEntity(entity);
            host.AddNewlyCreatedDBObject(entity, true);
            return id;
        }

        /// <summary>
        /// 将一组实体添加到AutoCAD图形数据库中的模型空间块表记录（BlockTableRecord）。
        /// </summary>
        /// <typeparam name="TEntity">实体类型，必须继承自AutoCAD的Entity类。</typeparam>
        /// <param name="entities">要添加到数据库的实体集合。</param>
        /// <param name="host">当前的事务对象，用于管理对数据库的操作。</param>
        /// <param name="model_space">模型空间块表记录，实体将被添加到这个记录中。</param>
        /// <returns>返回一个包含所有添加到数据库后实体的ObjectId的列表。</returns>
        /// <remarks>
        /// 此方法执行以下操作：
        /// 1. 对传入的实体集合中的每个实体执行添加操作。
        /// 2. 将每个实体附加到指定的模型空间块表记录。
        /// 3. 将新创建的实体添加到事务中，确保实体被正确地管理。
        /// 如果传入的实体集合为空或包含null元素，则这些元素将被忽略，不会添加到数据库中。
        /// </remarks>
        public static List<ObjectId> AddToDatabase<TEntity>(this ICollection<TEntity> entities, Transaction host, BlockTableRecord model_space)
            where TEntity : Entity
        {
            return entities.Select(entity =>
            {
                var id = model_space.AppendEntity(entity);
                host.AddNewlyCreatedDBObject(entity, true);
                return id;
            }).ToList();
        }

        /// <summary>
        /// 将一组实体添加到AutoCAD图形数据库中的指定块表记录（BlockTableRecord）。
        /// </summary>
        /// <typeparam name="TEntity">实体类型，必须继承自AutoCAD的Entity类。</typeparam>
        /// <param name="trans">当前的事务对象，用于管理对数据库的操作。</param>
        /// <param name="btr">块表记录对象，实体将被添加到这个记录中。</param>
        /// <param name="entities">要添加到数据库的实体数组。</param>
        /// <returns>返回一个包含所有添加到数据库后实体的ObjectId的列表。</returns>
        /// <remarks>
        /// 此方法执行以下操作：
        /// 1. 对传入的实体数组中的每个实体执行添加操作。
        /// 2. 将每个实体附加到指定的块表记录。
        /// 3. 将新创建的实体添加到事务中，确保实体被正确地管理。
        /// 如果传入的实体数组为空或包含null元素，则这些元素将被忽略，不会添加到数据库中。
        /// </remarks>
        public static List<ObjectId> AddEntityToDatabase<TEntity>(this Transaction trans, BlockTableRecord btr, params TEntity[] entities)
            where TEntity : Entity
        {
            return entities.Select(entity =>
            {
                var id = btr.AppendEntity(entity);
                trans.AddNewlyCreatedDBObject(entity, true);
                return id;
            }).ToList();
        }

        /// <summary>
        /// 修改实体的颜色
        /// </summary>
        /// <param name="entityId">实体Id</param>
        /// <param name="newColorIndex">颜色index</param>
        public static void ModifyEntityColorIndex(this ObjectId entityId, short newColorIndex)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            var editor = doc.Editor;

            using (Transaction transaction = db.TransactionManager.StartTransaction())
            {
                // 打开图形数据库
                BlockTable blockTable = transaction.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                // 获取实体对象
                Entity entity = transaction.GetObject(entityId, OpenMode.ForWrite) as Entity;

                if (entity != null)
                {
                    // 修改颜色属性
                    entity.ColorIndex = newColorIndex;
                }

                transaction.Commit();
            }
        }
        /// <summary>
        /// 将图形对象添加到图形文件中
        /// </summary>
        /// <param name="db">图形数据库</param>
        /// <param name="entity">图形对象</param>
        /// <returns>图形的objectid</returns>
        public static ObjectId AddEntityToModelSpace(this Database db, Entity entity)
        {
            //声明ObjectId，用于返回
            ObjectId entityId = ObjectId.Null;
            //开启事务
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                //打开块表
                BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                //打开块表记录
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                //添加图形到块表记录
                entityId = btr.AppendEntity(entity);
                //更新数据信息
                trans.AddNewlyCreatedDBObject(entity, true);
                //提交
                trans.Commit();
            }
            return entityId;
        }
        /// <summary>
        /// 将图形对象添加到图形文件中
        /// </summary>
        /// <param name="db">图形数据库</param>
        /// <param name="entity">图形对象，可变参数</param>
        /// <returns>图形的objectId，数组返回</returns>
        public static ObjectId[] AddEntityToModelSpace(this Database db, params Entity[] entity)
        {
            //声明ObjectId 用于返回
            ObjectId[] entityId = new ObjectId[entity.Length];
            //开启事务
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                //打开块表
                BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                // 打开块表记录
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

                for (int i = 0; i < entity.Length; i++)
                {
                    //添加图形到块表记录
                    entityId[i] = btr.AppendEntity(entity[i]);
                    //更新数据消息
                    trans.AddNewlyCreatedDBObject(entity[i], true);
                }
                trans.Commit();
            }
            return entityId;
        }
        /// <summary>
        /// 修改图形颜色(未添加到图形数据库)
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="colorIndex">颜色index</param>
        public static void ChangeEntityColor<TEntity>(this TEntity entity, short colorIndex, Document doc)
            where TEntity : Entity
        {
            Database db = doc.Database;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                entity.ColorIndex = colorIndex;

                tr.Commit();
            }
        }
        /// <summary>
        /// 修改图形颜色
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="colorIndex">颜色Index</param>
        public static void ChangeEntityColor2<TEntity>(this TEntity entity, short colorIndex, Document doc)
                        where TEntity : Entity
        {

            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {
                BlockTable blockTable = tr.GetObject(doc.Database.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = tr.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                Entity existingEntity = tr.GetObject(entity.ObjectId, OpenMode.ForWrite) as Entity;
                if (existingEntity != null)
                {
                    existingEntity.ColorIndex = colorIndex;
                }

                tr.Commit();
            }
        }


        /// <summary>
        /// 选择一个对象
        /// </summary>
        /// <param name="ed"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public static ObjectId SelectOne(this Editor ed, SelectionFilter filter = default)
        {
            if (ed is null) return ObjectId.Null;
            var value = ed.GetSelection(filter).Value;
            if (value is null) return ObjectId.Null;
            return value.GetObjectIds().FirstOrDefault();
        }



        /// <summary>
        /// 删除图形对象
        /// </summary>
        /// <param name="entity">图形对象的ObjectId</param>
        public static void EraseEntity(this ObjectId entity)
        {
            //打开事务处理
            using (Transaction trans = entity.Database.TransactionManager.StartTransaction())
            {
                //打开要删除的图形对象
                Entity ent = (Entity)entity.GetObject(OpenMode.ForWrite);
                //删除
                ent.Erase();
                trans.Commit();
            }
        }
        /// <summary>
        /// 删除图形对象
        /// </summary>
        /// <param name="entIds">图形对象的ObjectId</param>
        public static void EraseEntities(params ObjectId[] entIds)
        {
            if (entIds.Count() == 0)
                return;
            foreach (var entId in entIds)
            {
                using (Transaction trans = entId.Database.TransactionManager.StartTransaction())
                {
                    var ent = (Entity)entId.GetObject(OpenMode.ForWrite);
                    ent.Erase();
                    trans.Commit();
                }
            }
        }
        #region  Erase
        ///// <summary>
        ///// 删除图形对象
        ///// </summary>
        ///// <typeparam name="TEntity"></typeparam>
        ///// <param name="entities"></param>
        //public static void EraseEntities<TEntity>(this Database db , params TEntity[] entities)
        //    where TEntity : Entity
        //{
        //    if (entities.Count() == 0) return;
        //    foreach (var ent in entities)
        //    {
        //        using (Transaction trans = db.TransactionManager.StartTransaction())
        //        {
        //            //var ent = (Entity)entId.ObjectId.GetObject(OpenMode.ForWrite);
        //            ent.Erase();
        //            trans.Commit();
        //        }
        //    }
        //}
        ///// <summary>
        ///// 删除图形对象
        ///// </summary>
        ///// <param name="entity">图形对象的ObjectId</param>
        //public static void EraseEntity<TEntity>(this TEntity entity)
        //    where TEntity : Entity
        //{
        //    //打开事务处理
        //    using (Transaction trans = entity.Database.TransactionManager.StartTransaction())
        //    {
        //        //打开要删除的图形对象
        //        //Entity ent = (Entity)entity.ObjectId.GetObject(OpenMode.ForWrite);
        //        //删除
        //        entity.Erase();
        //        trans.Commit();
        //    }
        //}

        #endregion

        /// <summary>
        /// 通过ObjectId得到实体
        /// </summary>
        /// <param name="objIds">实体id</param>
        /// <param name="db">图像数据库</param>
        /// <returns></returns>
        public static Entity[] GetEntity(this ObjectId[] objIds, Database db)
        {

            Entity[] ents = new Entity[objIds.Length];
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                for (int i = 0; i < objIds.Length; i++)
                {
                    DBObject dBObj = objIds[i].GetObject(OpenMode.ForRead);
                    ents[i] = (Entity)dBObj;
                }
            }
            return ents;
        }
        /// <summary>
        /// 通过ObjectId得到实体
        /// </summary>
        /// <param name="objId">实体id</param>
        /// <param name="db">图像数据库</param>
        /// <returns></returns>
        public static Entity GetEntity(this ObjectId objId, Database db)
        {

            Entity ent = null;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {

                DBObject dBObj = objId.GetObject(OpenMode.ForRead);
                ent = (Entity)dBObj;

            }
            return ent;
        }














        /// <summary>
        /// 通过ObjectId获取指定类型的实体
        /// </summary>
        /// <typeparam name="TEntity">实体类型（必须继承自Entity）</typeparam>
        /// <param name="objId">实体ObjectId</param>
        /// <param name="openMode">打开模式（默认ForRead）</param>
        /// <param name="openErased">是否打开已删除对象（默认false）</param>
        /// <returns>指定类型的实体，失败返回null</returns>
        public static TEntity GetEntity<TEntity>(this Document doc ,  ObjectId objId, OpenMode openMode = OpenMode.ForRead, bool openErased = false)
            where TEntity : Entity
        {
            // 参数验证
            if (objId == null || objId.IsNull || !objId.IsValid)
            {
                doc?.Editor.WriteMessage("\n错误：无效的实体ID");
                return null;
            }

            if (!openErased && objId.IsErased)
            {
                doc?.Editor.WriteMessage("\n警告：实体已被删除");
                return null;
            }

            Transaction tr = null;
            try
            {
                Database db = objId.Database;
                tr = db.TransactionManager.StartTransaction();

                // 获取实体对象
                DBObject dbObj = tr.GetObject(objId, openMode);
                if (dbObj == null)
                {
                    doc?.Editor.WriteMessage("\n错误：无法获取实体对象");
                    return null;
                }

                // 转换为指定类型
                TEntity entity = dbObj as TEntity;
                if (entity == null)
                {
                    doc?.Editor.WriteMessage($"\n错误：实体类型不匹配，期望 {typeof(TEntity).Name}");
                    return null;
                }

                tr.Commit();
                return entity;
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                tr?.Abort();
                doc?.Editor.WriteMessage($"\nCAD错误：{ex.Message}");
                return null;
            }
            catch (System.Exception ex)
            {
                tr?.Abort();
                doc?.Editor.WriteMessage($"\n系统错误：{ex.Message}");
                return null;
            }
            finally
            {
                tr?.Dispose();
            }
        }

        /// <summary>
        /// 通过ObjectId获取实体（非泛型版本）
        /// </summary>
        /// <param name="objId">实体ObjectId</param>
        /// <param name="openMode">打开模式（默认ForRead）</param>
        /// <param name="openErased">是否打开已删除对象（默认false）</param>
        /// <returns>实体对象，失败返回null</returns>
        public static Entity GetEntity(this  Document doc, ObjectId objId, OpenMode openMode = OpenMode.ForRead, bool openErased = false)
        {
            return doc.GetEntity<Entity>(objId , openMode, openErased);
        }


















        /// <summary>
        /// 通过ObjectId获取指定类型的实体
        /// </summary>
        /// <typeparam name="TEntity">实体类型（必须继承自Entity）</typeparam>
        /// <param name="objId">实体ObjectId</param>
        /// <param name="openMode">打开模式（默认ForRead）</param>
        /// <param name="openErased">是否打开已删除对象（默认false）</param>
        /// <returns>指定类型的实体，失败返回null</returns>
        public static TEntity GetEntity<TEntity>(this Editor ed, ObjectId objId, OpenMode openMode = OpenMode.ForRead, bool openErased = false)
            where TEntity : Entity
        {
            // 参数验证
            if (objId == null || objId.IsNull || !objId.IsValid)
            {
                ed.WriteMessage("\n错误：无效的实体ID");
                return null;
            }

            if (!openErased && objId.IsErased)
            {
                ed.WriteMessage("\n警告：实体已被删除");
                return null;
            }

            Transaction tr = null;
            try
            {
                Database db = objId.Database;
                tr = db.TransactionManager.StartTransaction();

                // 获取实体对象
                DBObject dbObj = tr.GetObject(objId, openMode);
                if (dbObj == null)
                {
                    ed.WriteMessage("\n错误：无法获取实体对象");
                    return null;
                }

                // 转换为指定类型
                TEntity entity = dbObj as TEntity;
                if (entity == null)
                {
                    ed.WriteMessage($"\n错误：实体类型不匹配，期望 {typeof(TEntity).Name}");
                    return null;
                }

                tr.Commit();
                return entity;
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                tr?.Abort();
                ed.WriteMessage($"\nCAD错误：{ex.Message}");
                return null;
            }
            catch (System.Exception ex)
            {
                tr?.Abort();
                ed.WriteMessage($"\n系统错误：{ex.Message}");
                return null;
            }
            finally
            {
                tr?.Dispose();
            }
        }

        /// <summary>
        /// 通过ObjectId获取实体（非泛型版本）
        /// </summary>
        /// <param name="objId">实体ObjectId</param>
        /// <param name="openMode">打开模式（默认ForRead）</param>
        /// <param name="openErased">是否打开已删除对象（默认false）</param>
        /// <returns>实体对象，失败返回null</returns>
        public static Entity GetEntity(this Editor ed, ObjectId objId, OpenMode openMode = OpenMode.ForRead, bool openErased = false)
        {
            return ed.GetEntity<Entity>(objId, openMode, openErased);
        }










        /// <summary>
        /// 通过ObjectId得到实体
        /// </summary>
        /// <param name="objId"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        public static Entity GetEntity(this Database db, ObjectId objId)
        {

            Entity ent = null;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {

                DBObject dBObj = objId.GetObject(OpenMode.ForRead);
                ent = (Entity)dBObj;

            }
            return ent;
        }

        /// <summary>
        /// 通过圆心、起点夹角绘制圆弧
        /// </summary>
        /// <param name="db">图形数据库</param>
        /// <param name="center">圆心</param>
        /// <param name="startPoint">起点</param>
        /// <param name="degree">夹角,角度值</param>
        /// <returns>ObjectId</returns>
        public static ObjectId AddArcToModelSpace(this Database db, Point3d center, Point3d startPoint, double degree)
        {
            //获取半径
            double radius = center.DistanceTo(startPoint);
            //获取起点角度
            double startAngle = center.GetAngleToXAxis(startPoint);
            //声明圆弧对象
            Arc arc = new Arc(center, radius, startAngle, startAngle + degree.DegreeToAngle());
            return db.AddEntityToModelSpace(arc);
        }
        ///// <summary>
        ///// 绘制圆弧
        ///// </summary>
        ///// <param name="db">图形数据库</param>
        ///// <param name="startPoint">圆弧的起始点</param>
        ///// <param name="pointOnArc"></param>
        ///// <param name="endPoint">圆弧的终止点</param>
        ///// <returns>ObjectId</returns>
        //public static ObjectId AddArcToModelSpace(this Database db, Point3d startPoint, Point3d pointOnArc, Point3d endPoint)
        //{
        //    //创建几何类对象
        //    CircularArc3d cArc = new CircularArc3d(startPoint, pointOnArc, endPoint);
        //    //先判断三点是否在同一条直线上
        //    if (startPoint.IsOnOneLine(pointOnArc, endPoint))
        //    {
        //        return ObjectId.Null;
        //    }
        //    //创建圆弧对象
        //    Arc arc = new Arc(cArc.Center, cArc.Radius, cArc.Center.GetAngleToXAxis(startPoint), cArc.Center.GetAngleToXAxis(endPoint));
        //    // 加入图形数据库
        //    return db.AddEntityToModelSpace(arc);
        //}



        /// <summary>
        /// 通过三点绘制圆弧（起点、圆弧上一点、终点）
        /// </summary>
        /// <param name="db">图形数据库</param>
        /// <param name="startPoint">圆弧的起始点</param>
        /// <param name="pointOnArc">圆弧上的点</param>
        /// <param name="endPoint">圆弧的终止点</param>
        /// <returns>圆弧的ObjectId，失败返回ObjectId.Null</returns>
        public static ObjectId AddArcToModelSpace(this Database db, Point3d startPoint, Point3d pointOnArc, Point3d endPoint)
        {
            // 参数验证
            if (db == null)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：数据库不能为null");
                return ObjectId.Null;
            }

            if (!IsValidPoint(startPoint) || !IsValidPoint(pointOnArc) || !IsValidPoint(endPoint))
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：无效的点坐标");
                return ObjectId.Null;
            }

            // 检查三点是否共线
            if (ArePointsCollinear(startPoint, pointOnArc, endPoint))
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：三点共线，无法创建圆弧");
                return ObjectId.Null;
            }

            Transaction tr = null;
            try
            {
                tr = db.TransactionManager.StartTransaction();

                // 创建几何圆弧对象
                CircularArc3d cArc = new CircularArc3d(startPoint, pointOnArc, endPoint);

                // 检查圆弧有效性
                if (cArc.Radius < 1e-10)
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n错误：圆弧半径太小");
                    return ObjectId.Null;
                }

                // 计算角度（使用Vector2d避免Vector3d.Angle错误）
                Vector2d startVector = new Vector2d(startPoint.X - cArc.Center.X, startPoint.Y - cArc.Center.Y);
                Vector2d endVector = new Vector2d(endPoint.X - cArc.Center.X, endPoint.Y - cArc.Center.Y);

                double startAngle = startVector.Angle;
                double endAngle = endVector.Angle;

                // 确定圆弧方向（确保通过pointOnArc点）
                if (!IsPointOnArc(cArc.Center, cArc.Radius, startAngle, endAngle, pointOnArc))
                {
                    // 如果点不在默认弧上，交换起始和终止角度
                    double temp = startAngle;
                    startAngle = endAngle;
                    endAngle = temp;
                }

                // 确保角度范围正确（0 到 2π）
                startAngle = NormalizeAngle(startAngle);
                endAngle = NormalizeAngle(endAngle);

                // 创建圆弧对象
                Arc arc = new Arc(cArc.Center, Vector3d.ZAxis, cArc.Radius, startAngle, endAngle);

                // 设置圆弧属性
                arc.SetDatabaseDefaults();

                // 验证圆弧确实通过三个点
                if (!ValidateArcPoints(arc, startPoint, pointOnArc, endPoint))
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage("\n警告：创建的圆弧可能不精确通过指定点");
                }

                // 加入图形数据库
                ObjectId arcId = db.AddEntityToModelSpace(arc);

                tr.Commit();
                return arcId;
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                tr?.Abort();
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage($"\nCAD错误：{ex.Message}");
                return ObjectId.Null;
            }
            catch (System.Exception ex)
            {
                tr?.Abort();
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage($"\n系统错误：{ex.Message}");
                return ObjectId.Null;
            }
            finally
            {
                tr?.Dispose();
            }
        }

        /// <summary>
        /// 检查点是否在圆弧上
        /// </summary>
        public static bool IsPointOnArc(Point3d center, double radius, double startAngle, double endAngle, Point3d testPoint, double tolerance = 1e-5)
        {
            // 计算测试点相对于圆心的角度
            Vector2d testVector = new Vector2d(testPoint.X - center.X, testPoint.Y - center.Y);
            double testAngle = testVector.Angle;
            testAngle = NormalizeAngle(testAngle);

            // 计算测试点到圆心的距离
            double distance = center.DistanceTo(testPoint);

            // 检查距离是否接近半径
            if (Math.Abs(distance - radius) > tolerance)
                return false;

            // 检查角度是否在起始和终止角度之间
            return IsAngleBetween(testAngle, startAngle, endAngle, tolerance);
        }












        /// <summary>
        /// 检查点是否在圆弧上
        /// </summary>
        /// <param name="arc">圆弧对象</param>
        /// <param name="testPoint">要检查的点</param>
        /// <param name="tolerance">误差容限</param>
        /// <returns>点是否在圆弧上</returns>
        public static bool IsPointOnArc(this Arc arc, Point3d testPoint, double tolerance = 1e-5)
        {
            if (arc == null || !IsValidPoint(testPoint))
                return false;

            // 计算测试点到圆心的距离
            double distance = arc.Center.DistanceTo(testPoint);

            // 检查距离是否接近半径（考虑误差）
            if (Math.Abs(distance - arc.Radius) > tolerance)
                return false;

            // 计算测试点相对于圆心的角度
            Vector2d testVector = new Vector2d(testPoint.X - arc.Center.X, testPoint.Y - arc.Center.Y);
            double testAngle = testVector.Angle;
            testAngle = NormalizeAngle(testAngle);

            // 获取圆弧的起始和终止角度
            double startAngle = NormalizeAngle(arc.StartAngle);
            double endAngle = NormalizeAngle(arc.EndAngle);

            // 检查角度是否在圆弧角度范围内
            return IsAngleInArcRange(testAngle, startAngle, endAngle, arc.IsCounterClockwise(), tolerance);
        }

        /// <summary>
        /// 检查点是否在圆弧上（重载版本）
        /// </summary>
        /// <param name="center">圆心</param>
        /// <param name="radius">半径</param>
        /// <param name="startAngle">起始角度（弧度）</param>
        /// <param name="endAngle">终止角度（弧度）</param>
        /// <param name="isCounterClockwise">是否逆时针方向</param>
        /// <param name="testPoint">要检查的点</param>
        /// <param name="tolerance">误差容限</param>
        /// <returns>点是否在圆弧上</returns>
        public static bool IsPointOnArc(Point3d center, double radius, double startAngle, double endAngle,
                                       bool isCounterClockwise, Point3d testPoint, double tolerance = 1e-5)
        {
            if (!IsValidPoint(center) || !IsValidPoint(testPoint) || radius <= 0)
                return false;

            // 计算测试点到圆心的距离
            double distance = center.DistanceTo(testPoint);

            // 检查距离是否接近半径
            if (Math.Abs(distance - radius) > tolerance)
                return false;

            // 计算测试点相对于圆心的角度
            Vector2d testVector = new Vector2d(testPoint.X - center.X, testPoint.Y - center.Y);
            double testAngle = testVector.Angle;
            testAngle = NormalizeAngle(testAngle);

            // 规范化起始和终止角度
            startAngle = NormalizeAngle(startAngle);
            endAngle = NormalizeAngle(endAngle);

            // 检查角度是否在圆弧角度范围内
            return IsAngleInArcRange(testAngle, startAngle, endAngle, isCounterClockwise, tolerance);
        }

        /// <summary>
        /// 检查角度是否在圆弧角度范围内
        /// </summary>
        private static bool IsAngleInArcRange(double testAngle, double startAngle, double endAngle,
                                             bool isCounterClockwise, double tolerance = 1e-5)
        {
            if (isCounterClockwise)
            {
                // 逆时针方向
                if (startAngle <= endAngle)
                {
                    return testAngle >= startAngle - tolerance && testAngle <= endAngle + tolerance;
                }
                else
                {
                    // 跨越0度的情况
                    return testAngle >= startAngle - tolerance || testAngle <= endAngle + tolerance;
                }
            }
            else
            {
                // 顺时针方向
                if (startAngle >= endAngle)
                {
                    return testAngle <= startAngle + tolerance && testAngle >= endAngle - tolerance;
                }
                else
                {
                    // 跨越0度的情况
                    return testAngle <= startAngle + tolerance || testAngle >= endAngle - tolerance;
                }
            }
        }

        /// <summary>
        /// 判断圆弧是否为逆时针方向
        /// </summary>
        public static bool IsCounterClockwise(this Arc arc)
        {
            if (arc == null) return true; // 默认假设为逆时针

            // 通过起始角度和终止角度判断方向
            double startAngle = NormalizeAngle(arc.StartAngle);
            double endAngle = NormalizeAngle(arc.EndAngle);

            // 如果规范化后的起始角度小于终止角度，通常为逆时针
            // 但需要考虑圆弧跨越0度的情况
            if (startAngle < endAngle)
            {
                return (endAngle - startAngle) <= Math.PI;
            }
            else
            {
                return (startAngle - endAngle) > Math.PI;
            }
        }











        /// <summary>
        /// 规范化角度到 0 到 2π 范围
        /// </summary>
        private static double NormalizeAngle(double angle)
        {
            while (angle < 0) angle += 2 * Math.PI;
            while (angle >= 2 * Math.PI) angle -= 2 * Math.PI;
            return angle;
        }

        /// <summary>
        /// 检查角度是否在两个角度之间
        /// </summary>
        private static bool IsAngleBetween(double testAngle, double startAngle, double endAngle, double tolerance = 1e-5)
        {
            // 处理跨越0度的情况
            if (startAngle > endAngle)
            {
                return testAngle >= startAngle - tolerance || testAngle <= endAngle + tolerance;
            }
            else
            {
                return testAngle >= startAngle - tolerance && testAngle <= endAngle + tolerance;
            }
        }

        /// <summary>
        /// 验证圆弧是否通过指定的三个点
        /// </summary>
        private static bool ValidateArcPoints(Arc arc, Point3d p1, Point3d p2, Point3d p3, double tolerance = 0.1)
        {
            double d1 = arc.GetDistanceToPoint(p1);
            double d2 = arc.GetDistanceToPoint(p2);
            double d3 = arc.GetDistanceToPoint(p3);

            return d1 < tolerance && d2 < tolerance && d3 < tolerance;
        }

        /// <summary>
        /// 计算点到圆弧的距离
        /// </summary>
        private static double GetDistanceToPoint(this Arc arc, Point3d point)
        {
            // 简单实现：计算点到圆心的距离与半径的差值
            return Math.Abs(arc.Center.DistanceTo(point) - arc.Radius);
        }

        /// <summary>
        /// 检查三点是否共线
        /// </summary>
        private static bool ArePointsCollinear(Point3d p1, Point3d p2, Point3d p3, double tolerance = 1e-10)
        {
            Vector3d v1 = p2 - p1;
            Vector3d v2 = p3 - p1;

            Vector3d crossProduct = v1.CrossProduct(v2);
            return crossProduct.Length < tolerance;
        }

        /// <summary>
        /// 绘制圆弧
        /// </summary>
        /// <param name="db">图形数据库</param>
        /// <param name="center">圆弧所在圆的圆心点</param>
        /// <param name="radius">圆弧的半径</param>
        /// <param name="startDegree">圆弧的起始角度</param>
        /// <param name="endDegree">圆弧的终止角度</param>
        /// <returns>ObjectId</returns>
        public static ObjectId AddArcToModelSpace(this Database db, Point3d center, double radius, double startDegree, double endDegree)
        {
            return db.AddEntityToModelSpace(new Arc(center, radius, startDegree.DegreeToAngle(), endDegree.DegreeToAngle()));
        }
        /// <summary>
        /// 绘制直线 
        /// </summary>
        /// <param name="db">图形数据库</param>
        /// <param name="startPoint">起点坐标</param>
        /// <param name="length">直线长度</param>
        /// <param name="degree">与x轴正方向的角度</param>
        /// <returns>ObjectId</returns>
        public static ObjectId AddLineToModelSpace(this Database db, Point3d startPoint, double length, double degree)
        {
            //计算终点坐标
            double x = startPoint.X + length * System.Math.Cos(degree.DegreeToAngle());
            double y = startPoint.Y + length * System.Math.Sin(degree.DegreeToAngle());
            Point3d endPoint = new Point3d(x, y, 0);
            return db.AddEntityToModelSpace(new Line(startPoint, endPoint));
        }
        /// <summary>
        /// 删除图形
        /// </summary>
        /// <param name="doc">当前文档</param>
        /// <param name="entityIds">实体id</param>
        /// <returns>是否删除成功</returns>
        public static bool DeleteEntities(this Document doc, List<ObjectId> entityIds)
        {
            Database db = doc.Database;
            Editor editor = doc.Editor;

            var result = true;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                var blockTable = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord currentSpace = tr.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                foreach (ObjectId entityId in entityIds)
                {
                    Entity entity = tr.GetObject(entityId, OpenMode.ForWrite) as Entity;

                    if (entity != null)
                    {
                        entity.Erase();
                        result = true;
                    }
                }

                tr.Commit();
            }
            return result;
        }


        /// <summary>
        /// 删除图像数据库实体
        /// </summary>
        /// <param name="doc">当前文档</param>
        /// <param name="entityIds">实体id</param>
        /// <returns>是否删除成功</returns>
        public static bool DeleteEntities(this Document doc, params ObjectId[] entityIds)
        {
            Database db = doc.Database;
            Editor editor = doc.Editor;

            var result = true;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                var blockTable = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord currentSpace = tr.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                foreach (ObjectId entityId in entityIds)
                {
                    Entity entity = tr.GetObject(entityId, OpenMode.ForWrite) as Entity;

                    if (entity != null)
                    {
                        entity.Erase();
                        result = true;
                    }
                }

                tr.Commit();
            }
            return result;
        }

        /// <summary>
        /// 删除图像数据库实体
        /// </summary>
        /// <param name="doc">文档</param>
        /// <param name="entityId">实体id</param>
        /// <returns></returns>
        public static bool DeleteEntity(this Document doc, ObjectId entityId)
        {
            Database db = doc.Database;

            var result = false;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                var blockTable = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord currentSpace = tr.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;


                Entity entity = tr.GetObject(entityId, OpenMode.ForWrite) as Entity;

                if (entity != null)
                {
                    entity.Erase();
                    result = true;
                }


                tr.Commit();
            }
            return result;
        }


        public static ObjectId[] AddEntityToModelSpace<TEntity>(this Database db, ICollection<TEntity> entitys)
    where TEntity : Entity
        {
            //声明ObjectId 用于返回
            ObjectId[] entityId = new ObjectId[entitys.Count];
            //开启事务
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                //打开块表
                var bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                // 打开块表记录
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

                //for (int i = 0; i < polyline.Count; i++)
                //{
                //    //添加图形到块表记录
                //    entityId[i] = btr.AppendEntity(polyline[i]);
                //    //更新数据消息
                //    trans.AddNewlyCreatedDBObject(polyline[i], true);
                //}
                int i = 0;
                foreach (var entity in entitys)
                {
                    //添加图形到块表记录
                    entityId[i] = btr.AppendEntity(entity);
                    //更新数据消息
                    trans.AddNewlyCreatedDBObject(entity, true);
                    i++;
                }
                trans.Commit();
            }

            return entityId;
        }

        /// <summary>
        /// 使用 ObjectId 来判断一个实体是否已经添加到图形数据库 zheli 111
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        public static bool IsEntityInDatabase(this Entity entity)
        {
            ObjectId entityId = entity.ObjectId;

            if (entityId.IsNull || entityId.IsErased)
            {
                // 实体的ObjectId为Null或已被删除
                return false;
            }

            using (Transaction transaction = entityId.Database.TransactionManager.StartTransaction())
            {
                Entity currentEntity = transaction.GetObject(entityId, OpenMode.ForRead) as Entity;

                if (currentEntity == null || currentEntity.IsErased)
                {
                    // 实体在数据库中不存在或已被删除
                    return false;
                }

                // 实体存在于数据库中
                return true;
            }
        }
        /// <summary>
        /// 安全删除实体（处理锁定图层等情况）
        /// </summary>
        public static void SafeEraseEntity<TEntity>(TEntity ent, Transaction tr)
            where TEntity : Entity
        {
            try
            {
                // 确保实体所在图层已解锁
                LayerTableRecord layer = (LayerTableRecord)tr.GetObject(
                    ent.LayerId, OpenMode.ForWrite);
                if (layer.IsLocked)
                {
                    layer.IsLocked = false;
                }

                ent.UpgradeOpen();
                ent.Erase();
            }
            catch
            {
                // 忽略删除失败的实体
            }
        }





















        /// <summary>
        /// 设置实体颜色、图层（安全版本）
        /// </summary>
        /// <typeparam name="TEntity">实体类型，必须继承自AutoCAD的Entity类</typeparam>
        /// <param name="entity">实体</param>
        /// <param name="colorIndex">颜色索引</param>
        /// <param name="layerName">图层名字</param>
        /// <param name="createIfNotExists">如果图层不存在是否创建</param>
        /// <param name="layerColorIndex">图层颜色索引（可选）</param>
        public static void SetColorLayer<TEntity>(this TEntity entity, short colorIndex, string layerName,
            bool createIfNotExists = true, short layerColorIndex = 256) where TEntity : Entity
        {
            if (entity == null)
                throw new ArgumentNullException(nameof(entity));

            if (string.IsNullOrEmpty(layerName))
                throw new ArgumentException("图层名称不能为空", nameof(layerName));

            Database db = entity.Database;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                try
                {
                    // 首先确保实体以写模式打开
                    TEntity entityForWrite = tr.GetObject(entity.ObjectId, OpenMode.ForWrite) as TEntity;
                    if (entityForWrite == null)
                    {
                        throw new System.Exception("无法以写模式打开实体");
                    }

                    LayerTable layerTable = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;

                    // 检查图层是否存在
                    if (layerTable.Has(layerName))
                    {
                        // 图层存在，直接设置
                        entityForWrite.Layer = layerName;
                    }
                    else if (createIfNotExists)
                    {
                        // 创建新图层
                        CreateLayerWithTransaction(db, layerName, layerColorIndex, tr);
                        entityForWrite.Layer = layerName;
                    }
                    else
                    {
                        // 使用当前图层
                        entityForWrite.Layer = GetCurrentLayerName(db, tr);
                    }

                    // 设置颜色
                    entityForWrite.ColorIndex = colorIndex;

                    tr.Commit();
                }
                catch (Exception ex)
                {
                    tr.Abort();
                    throw new System.Exception($"设置实体颜色图层失败: {ex.Message}", ex);
                }
            }
        }

        /// <summary>
        /// 获取当前图层名称
        /// </summary>
        private static string GetCurrentLayerName(Database db, Transaction tr)
        {
            try
            {
                LayerTableRecord layerRecord = tr.GetObject(db.Clayer, OpenMode.ForRead) as LayerTableRecord;
                return layerRecord?.Name ?? "0";
            }
            catch
            {
                return "0"; // 默认图层
            }
        }

        /// <summary>
        /// 在事务中创建图层
        /// </summary>
        private static void CreateLayerWithTransaction(Database db, string layerName, short colorIndex, Transaction tr)
        {
            LayerTable layerTable = tr.GetObject(db.LayerTableId, OpenMode.ForWrite) as LayerTable;

            // 双重检查图层是否已存在
            if (!layerTable.Has(layerName))
            {
                LayerTableRecord layerRecord = new LayerTableRecord
                {
                    Name = layerName,
                    Color = Color.FromColorIndex(ColorMethod.ByAci, colorIndex),
                    IsPlottable = true,
                    LineWeight = LineWeight.LineWeight025
                };

                layerTable.Add(layerRecord);
                tr.AddNewlyCreatedDBObject(layerRecord, true);
            }
        }

        /// <summary>
        /// 安全设置图层（不抛出异常）
        /// </summary>
        public static bool TrySetColorLayer<TEntity>(this TEntity entity, short colorIndex, string layerName,
            bool createIfNotExists = true, short layerColorIndex = 256) where TEntity : Entity
        {
            try
            {
                entity.SetColorLayer(colorIndex, layerName, createIfNotExists, layerColorIndex);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 设置实体为当前图层
        /// </summary>
        public static void SetToCurrentLayer<TEntity>(this TEntity entity, short colorIndex = 256) where TEntity : Entity
        {
            Database db = entity.Database;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                // 确保实体以写模式打开
                TEntity entityForWrite = tr.GetObject(entity.ObjectId, OpenMode.ForWrite) as TEntity;
                if (entityForWrite != null)
                {
                    string currentLayerName = GetCurrentLayerName(db, tr);
                    entityForWrite.Layer = currentLayerName;
                    entityForWrite.ColorIndex = colorIndex;
                }
                tr.Commit();
            }
        }




        #region 包围盒

        /// <summary>
        /// 包围盒和矩阵的结果结构
        /// </summary>
        public struct BlockBoxResult
        {
            public Extents3d Extents { get; set; }
            public Matrix3d Matrix { get; set; }

            public BlockBoxResult(Extents3d extents, Matrix3d matrix)
            {
                Extents = extents;
                Matrix = matrix;
            }

            public static BlockBoxResult Empty => new BlockBoxResult(new Extents3d(), Matrix3d.Identity);
        }

        /// <summary>
        /// 获取块的包围盒（.NET Framework 4.8 兼容版）
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns>BlockBoxResult 包含包围盒和变换矩阵</returns>
        public static BlockBoxResult GetBlockBox(this Entity entity)
        {
            return GetBlockBox(entity, Matrix3d.Identity);
        }

        /// <summary>
        /// 获取块的包围盒（内部实现）
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="matrix">变换矩阵</param>
        /// <returns>BlockBoxResult 包含包围盒和变换矩阵</returns>
        static BlockBoxResult GetBlockBox(this Entity entity, Matrix3d matrix)
        {
            if (entity == null)
                return BlockBoxResult.Empty;

            if (entity is BlockReference blockReference)
            {
                return ProcessBlockReference(blockReference, matrix);
            }
            else
            {
                return ProcessEntity(entity, matrix);
            }
        }

        /// <summary>
        /// 处理块引用
        /// </summary>
        private static BlockBoxResult ProcessBlockReference(BlockReference blockReference, Matrix3d matrix)
        {
            Extents3d extents = new Extents3d();
            Matrix3d transformedMatrix = matrix * blockReference.BlockTransform;

            // 处理块定义中的实体
            ProcessBlockTableRecordEntities(blockReference, transformedMatrix, ref extents);

            // 处理属性
            ProcessBlockAttributes(blockReference, matrix, ref extents);

            return new BlockBoxResult(extents, matrix);
        }

        /// <summary>
        /// 处理块表记录中的实体
        /// </summary>
        private static void ProcessBlockTableRecordEntities(BlockReference blockReference, Matrix3d matrix, ref Extents3d extents)
        {
            using (var btr = blockReference.BlockTableRecord.GetObject(OpenMode.ForRead) as BlockTableRecord)
            {
                if (btr == null) return;

                foreach (ObjectId id in btr)
                {
                    using (var entity = id.GetObject(OpenMode.ForRead, false, true) as Entity)
                    {
                        if (entity == null || !entity.Visible) continue;

                        // 跳过非常量或不可见的属性定义
                        if (entity is AttributeDefinition attributeDefinition)
                        {
                            if (!attributeDefinition.Constant || attributeDefinition.Invisible) continue;
                        }

                        var result = GetBlockBox(entity, matrix);
                        if (!result.Extents.IsEmptyExt())
                        {
                            if (extents.IsEmptyExt())
                                extents = result.Extents;
                            else
                                extents.AddExtents(result.Extents);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 处理块属性
        /// </summary>
        private static void ProcessBlockAttributes(BlockReference blockReference, Matrix3d matrix, ref Extents3d extents)
        {
            if (blockReference.AttributeCollection.Count == 0) return;

            foreach (ObjectId attId in blockReference.AttributeCollection)
            {
                using (var attributeReference = attId.GetObject(OpenMode.ForRead) as AttributeReference)
                {
                    if (attributeReference == null || attributeReference.Invisible || !attributeReference.Visible) continue;

                    var result = GetBlockBox(attributeReference, matrix);
                    if (!result.Extents.IsEmptyExt())
                    {
                        if (extents.IsEmptyExt())
                            extents = result.Extents;
                        else
                            extents.AddExtents(result.Extents);
                    }
                }
            }
        }

        /// <summary>
        /// 处理普通实体
        /// </summary>
        private static BlockBoxResult ProcessEntity(Entity entity, Matrix3d matrix)
        {
            var entityExtents = GetEntityBoxEx(entity);
            if (!entityExtents.HasValue)
                return BlockBoxResult.Empty;

            if (IsUniscaledOrtho(matrix))
            {
                return ProcessUniscaledOrthoEntity(entity, matrix, entityExtents.Value);
            }
            else
            {
                return ProcessTransformedEntity(entityExtents.Value, matrix);
            }
        }

        /// <summary>
        /// 处理均匀缩放正交变换的实体
        /// </summary>
        private static BlockBoxResult ProcessUniscaledOrthoEntity(Entity entity, Matrix3d matrix, Extents3d entityExtents)
        {
            using (var transformedEntity = entity.GetTransformedCopy(matrix))
            {
                var transformedExtents = GetEntityBoxEx(transformedEntity);
                return new BlockBoxResult(transformedExtents ?? new Extents3d(), matrix);
            }
        }

        /// <summary>
        /// 处理变换后的实体
        /// </summary>
        private static BlockBoxResult ProcessTransformedEntity(Extents3d entityExtents, Matrix3d matrix)
        {
            var transformedExtents = entityExtents;
            transformedExtents.TransformBy(matrix);
            return new BlockBoxResult(transformedExtents, matrix);
        }

        /// <summary>
        /// 检查矩阵是否为均匀缩放正交矩阵
        /// </summary>
        private static bool IsUniscaledOrtho(Matrix3d matrix)
        {
            try
            {
                // 检查是否是正交矩阵
                if (!matrix.IsScaledOrtho())
                    return false;

                // 检查缩放因子是否为1（均匀缩放）
                Vector3d xAxis = matrix.CoordinateSystem3d.Xaxis;
                Vector3d yAxis = matrix.CoordinateSystem3d.Yaxis;
                Vector3d zAxis = matrix.CoordinateSystem3d.Zaxis;

                double scaleX = xAxis.Length;
                double scaleY = yAxis.Length;
                double scaleZ = zAxis.Length;

                // 检查三个方向的缩放因子是否相等（在容差范围内）
                const double tolerance = 1e-10;
                return Math.Abs(scaleX - scaleY) < tolerance &&
                       Math.Abs(scaleY - scaleZ) < tolerance &&
                       Math.Abs(scaleX - 1.0) < tolerance;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 扩展方法：检查Extents3d是否为空
        /// </summary>
        public static bool IsEmptyExt(this Extents3d extents)
        {
            return extents.MinPoint.X > extents.MaxPoint.X ||
                   extents.MinPoint.Y > extents.MaxPoint.Y ||
                   extents.MinPoint.Z > extents.MaxPoint.Z;
        }

        /// <summary>
        /// 获取实体包围盒
        /// </summary>
        private static Extents3d? GetEntityBoxEx(Entity entity)
        {
            try
            {
                return entity.GeometricExtents;
            }
            catch
            {
                return null;
            }
        }



        #endregion





        /// <summary>
        /// 设置多段线颜色、图层并闭合
        /// </summary>
        /// <param name="polyline">多段线</param>
        /// <param name="colorIndex">颜色索引</param>
        /// <param name="layerName">图层名字</param>
        /// <param name="isClosed">是否闭合</param>
        public static void SetPolylineColorLayer(this Polyline polyline, short colorIndex, string layerName, bool isClosed = true)
        {
            polyline.Closed = isClosed;
            polyline.Layer = layerName;
            polyline.ColorIndex = colorIndex; // 设置颜色
        }









        /// <summary>
        /// 设置实体的可见性（隐藏或显示）
        /// </summary>
        /// <param name="objectId">要操作的实体ID</param>
        /// <param name="isVisible">是否显示（true=显示，false=隐藏）</param>
        /// <returns>操作是否成功</returns>
        public static bool SetEntityVisibility(ObjectId objectId, bool isVisible)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            if (doc == null) return false;

            Database db = doc.Database;
            Editor ed = doc.Editor;

            try
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    // 获取实体对象（尝试以只读方式打开）
                    Entity entity = tr.GetObject(objectId, OpenMode.ForRead) as Entity;
                    if (entity == null)
                    {
                        ($"无法获取实体（ID: {objectId}），可能已被删除或无效。").CadMessage2(); ;
                        return false;
                    }

                    // 检查图层是否锁定
                    LayerTableRecord layer = tr.GetObject(entity.LayerId, OpenMode.ForRead) as LayerTableRecord;
                    if (layer != null && layer.IsLocked)
                    {
                        // 临时解锁图层（仅当前事务有效）
                        tr.Abort(); // 中止当前事务
                        bool unlockSuccess = doc.UnlockByLayer(layer.Name);
                        if (!unlockSuccess)
                        {
                            ($"无法解锁图层 '{layer.Name}'，操作终止。").CadMessage2(); ;
                            return false;
                        }

                        // 重新开始事务（因为之前的已中止）
                        using (Transaction newTr = db.TransactionManager.StartTransaction())
                        {
                            entity = newTr.GetObject(objectId, OpenMode.ForWrite) as Entity;
                            if (entity == null)
                            {
                                ($"重新获取实体失败（ID: {objectId}）。").CadMessage2(); ;
                                return false;
                            }

                            // 设置可见性
                            entity.Visible = isVisible;

                            newTr.Commit();
                            ($"实体（ID: {objectId}）已{(isVisible ? "显示" : "隐藏")}。").CadMessage2(); ;
                            return true;
                        }
                    }
                    else
                    {
                        // 图层未锁定，直接修改
                        entity.UpgradeOpen(); // 升级为可写模式
                        entity.Visible = isVisible;
                        tr.Commit();
                        ($"实体（ID: {objectId}）已{(isVisible ? "显示" : "隐藏")}。").CadMessage2(); ;
                        return true;
                    }
                }
            }
            catch (System.Exception ex)
            {
                ($"操作失败: {ex.Message}").CadMessage2();
                return false;
            }
        }




        /// <summary>
        /// 隐藏指定实体
        /// </summary>
        public static bool HideEntity(this ObjectId objectId) => SetEntityVisibility(objectId, false);

        /// <summary>
        /// 显示指定实体
        /// </summary>
        public static bool ShowEntity(this ObjectId objectId) => SetEntityVisibility(objectId, true);










        #region ObjectId - Entity 转换




        /// <summary>
        /// 将ObjectId集合转换为Entity集合
        /// </summary>
        /// <typeparam name="TEntity">实体类型（必须继承自Entity）</typeparam>
        /// <param name="objectIds">ObjectId集合</param>
        /// <param name="openMode">打开模式（默认ForRead）</param>
        /// <param name="openErased">是否打开已删除对象（默认false）</param>
        /// <returns>实体集合</returns>
        public static List<TEntity> ToEntities<TEntity>(
            this IEnumerable<ObjectId> objectIds,
            OpenMode openMode = OpenMode.ForRead,
            bool openErased = false) where TEntity : Entity
        {
            if (objectIds == null)
                return new List<TEntity>();

            Database db = objectIds.FirstOrDefault().Database;
            if (db == null)
                return new List<TEntity>();

            List<TEntity> entities = new List<TEntity>();

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                foreach (ObjectId id in objectIds)
                {
                    if (!id.IsValid || id.IsNull || (!openErased && id.IsErased))
                        continue;

                    try
                    {
                        TEntity entity = tr.GetObject(id, openMode) as TEntity;
                        if (entity != null)
                        {
                            entities.Add(entity);
                        }
                    }
                    catch
                    {
                        // 忽略转换失败的对象
                        continue;
                    }
                }
                tr.Commit();
            }

            return entities;
        }

        /// <summary>
        /// 将Entity集合转换为ObjectId集合
        /// </summary>
        /// <typeparam name="TEntity">实体类型（必须继承自Entity）</typeparam>
        /// <param name="entities">实体集合</param>
        /// <returns>ObjectId集合</returns>
        public static List<ObjectId> ToObjectIds<TEntity>(
            this IEnumerable<TEntity> entities) where TEntity : Entity
        {
            if (entities == null)
                return new List<ObjectId>();

            return entities
                .Where(e => e != null && e.ObjectId.IsValid)
                .Select(e => e.ObjectId)
                .ToList();
        }

        /// <summary>
        /// 将ObjectId集合转换为Entity集合（非泛型版本）
        /// </summary>
        public static List<Entity> ToEntities(
            this IEnumerable<ObjectId> objectIds,
            OpenMode openMode = OpenMode.ForRead,
            bool openErased = false)
        {
            return objectIds.ToEntities<Entity>(openMode, openErased);
        }




        #endregion




    }
}
